home *** CD-ROM | disk | FTP | other *** search
- ;;; -*- Mode:Lisp; Package:User; Base:10; Lowercase:T; Syntax:Common-Lisp -*-
- ;;; ===========================================================================
- ;;; Lisp Support
- ;;; ===========================================================================
- ;;; (c) Copyright 1989, 1991 Cornell University
-
- ;;; $Id: lisp-support.lisp,v 2.12 1991/10/04 22:43:27 rz Exp $
-
- (in-package "USER")
-
- #-Genera
- (defmacro weyli::lambda (args &body body)
- `(function (lambda ,args ,@body)))
-
- ;; The following is done instead of importing defgeneric and
- ;; defmethod, to avoid muddying the user package.
- #+PCL
- (progn
- (defmacro clos-defgeneric (&rest args) `(pcl:defgeneric . ,args))
- (defmacro clos-defmethod (&rest args) `(pcl:defmethod . ,args)))
-
- #+(and CLOS (not Allegro-v4.0))
- (progn
- (defmacro clos-defgeneric (&rest args) `(clos:defgeneric . ,args))
- (defmacro clos-defmethod (&rest args) `(clos:defmethod . ,args)))
-
- ;; Extend defmethod slightly
-
- #+PCL
- (defmacro weyli::defmethod (&rest args &environment env)
- (declare (pcl::arglist name
- {method-qualifier}*
- specialized-lambda-list
- &body body))
- (labels ((duplicate-arglist (arglist)
- (cond ((null arglist) (list nil))
- ((or (atom (first arglist))
- (null (rest (first arglist)))
- (atom (second (first arglist)))
- (not (eql 'or (first (second (first arglist))))))
- (mapcar (lambda (q) (cons (first arglist) q))
- (duplicate-arglist (rest arglist))))
- (t (loop for type in (rest (second (first arglist)))
- with rest = (duplicate-arglist (rest arglist))
- nconc (mapcar (lambda (q)
- (cons (list (first (first arglist)) type)
- q))
- rest))))))
- (multiple-value-bind (name qualifiers lambda-list body)
- (pcl::parse-defmethod args)
- (let ((proto-method (pcl::method-prototype-for-gf name)))
- `(progn
- ,@(loop for ll in (duplicate-arglist lambda-list)
- collect
- (pcl::expand-defmethod proto-method name qualifiers ll body env)))))))
-
- #+CLOS
- (defmacro weyli::defmethod (&rest args)
- (declare (arglist name
- {method-qualifier}*
- specialized-lambda-list
- &body body))
- (labels ((duplicate-arglist (arglist)
- (cond ((null arglist) (list nil))
- ((or (atom (first arglist))
- (null (rest (first arglist)))
- (atom (second (first arglist)))
- (not (eql 'or (first (second (first arglist))))))
- (mapcar (lambda (q) (cons (first arglist) q))
- (duplicate-arglist (rest arglist))))
- (t (loop for type in (rest (second (first arglist)))
- with rest = (duplicate-arglist (rest arglist))
- nconc (mapcar (lambda (q)
- (cons (list (first (first arglist)) type)
- q))
- rest))))))
- #-LispWorks
- (multiple-value-bind (name qualifiers lambda-list body)
- #+Lucid (clos::parse-defmethod args)
- #+Genera (clos-parse-defmethod args)
- `(progn
- ,@(loop for ll in (duplicate-arglist lambda-list)
- collect
- `(clos::defmethod ,name ,@qualifiers ,ll ,@body))))
- #+LispWorks
- (let ((name (first args)))
- (multiple-value-bind (qualifiers lambda-list body)
- (clos::parse-defmethod nil name (rest args))
- `(progn
- ,@(loop for ll in (duplicate-arglist lambda-list)
- collect
- `(clos:defmethod ,name ,@qualifiers ,ll ,@body)))))))
-
- #+(and Genera CLOS)
- (defun clos-parse-defmethod (form)
- (let ((name (pop form))
- qualifiers)
- (loop while (and (atom (first form))
- (not (null (first form))))
- do (push (pop form) qualifiers))
- (values name (reverse qualifiers) (first form) (rest form))))
-
- (defmacro weyli::%funcall (function &rest args)
- `(lisp:funcall ,function ,@args))
-
- (clos-defmethod weyli::funcall (function &rest args)
- (lisp:apply function args))
-
- (defmacro weyli::%apply (function &rest args)
- `(lisp:apply ,function ,@args))
-
- (clos-defmethod weyli::apply (function &rest args)
- (labels ((accum (args)
- (cond ((null (rest args))
- args)
- (t (cons (first args) (accum (rest args)))))))
- (cond ((null args)
- (error "The function APPLY was called with too few arguments"))
- (t (lisp:apply function (accum args))))))
-
- (clos-defgeneric weyli::delete (item set &key &allow-other-keys)
- )
-
- (clos-defmethod weyli::delete (item (sequence sequence) &rest args)
- (apply #'lisp:delete item sequence args))
-
- (clos-defgeneric weyli::member (item list &key &allow-other-keys)
- )
-
- (clos-defmethod weyli::member (item (list list) &rest args)
- (apply #'lisp:member item list args))
-
- (clos-defgeneric weyli::replace (item list &key &allow-other-keys)
- )
-
- (clos-defmethod weyli::replace ((item sequence) (list sequence) &rest args)
- (apply #'lisp:replace item list args))
-
- (clos-defgeneric weyli::substitute
- (newitem olditem sequence &key &allow-other-keys)
- )
-
- (clos-defmethod weyli::substitute (newitem olditem (seq sequence) &rest args)
- (apply #'lisp:substitute newitem olditem seq args))
-
- (clos-defgeneric weyli::map (result-type function sequence &rest sequences)
- )
-
- (clos-defmethod weyli::map (result-type function sequence &rest sequences)
- (apply #'lisp:map result-type function sequence sequences))
-
- (clos-defgeneric weyli::reduce (function sequence &rest options)
- )
-
- (clos-defmethod weyli::reduce (function (sequence sequence) &rest options)
- (apply #'lisp:reduce function sequence options))
-
-
- #+Genera
- (eval-when (compile load eval)
- ;; Link the value cells of algebra:* and zl:*, etc.
- (unless (eq (locf (symbol-value 'weyli::*))
- (locf (symbol-value 'zl:*)))
- (setq weyli::* zl:*)
- (si:link-symbol-value-cells 'weyli::* 'zl:*))
- (unless (eq (locf (symbol-value 'weyli::+))
- (locf (symbol-value 'zl:+)))
- (setq weyli::+ zl:+)
- (si:link-symbol-value-cells 'weyli::+ 'zl:+))
- )
-
- #+Lucid
- (setf (symbol-function 'lucid-old-top-level-eval) #'lucid::top-level-eval)
-
- #+Lucid
- (defun lucid::top-level-eval (&rest arguments)
- (declare (special weyli::* weyli::+ lisp:* lisp:+))
- (multiple-value-prog1 (apply #'lucid-old-top-level-eval arguments)
- (setq weyli::* lisp:*)
- (setq weyli::+ lisp:+)))
-
- (defmacro weyli::defsubst (function lambda-list &body body)
- `(#+Genera scl:defsubst
- #+Lucid lcl:defsubst
- #-(or Genera Lucid) defun
- ,function ,lambda-list ,@body))
-
- ;;Infinities...
-
- (defvar weyli::*positive-infinity*
- #+Genera si:infinite-positive-double-float
- #+Lucid system:float-positive-infinity)
-
- (defvar weyli::*negative-infinity*
- #+Genera si:infinite-negative-double-float
- #+Lucid system:float-negative-infinity)
-
- (defmacro weyli::copy-array-contents (from-array to-array)
- #+Genera
- `(scl:copy-array-contents ,from-array ,to-array)
- #-Genera
- `(copy-array-contents* ,from-array ,to-array))
-
- #+Lucid
- (defun copy-array-contents* (from-array to-array)
- (let ((from-dims (array-dimensions from-array))
- (to-dims (array-dimensions to-array)))
- (unless (eql (length from-dims) (length to-dims))
- (error "Incompatable array dimensions: ~A -> ~A"
- from-array to-array))
- (labels ((worker (from-dims to-dims indices)
- (cond ((null from-dims)
- (apply #'lucid-runtime-support:set-aref
- (apply #'aref from-array indices)
- to-array indices))
- (t (loop for i below (min (first from-dims)
- (first to-dims))
- do (worker (rest from-dims) (rest to-dims)
- (cons i indices)))))))
- (worker (reverse from-dims) (reverse to-dims) nil))))
-
-
- #+LispWorks
- (defun copy-array-contents* (from-array to-array)
- (let ((from-dims (array-dimensions from-array))
- (to-dims (array-dimensions to-array)))
- (unless (eql (length from-dims) (length to-dims))
- (error "Incompatable array dimensions: ~A -> ~A"
- from-array to-array))
- (labels ((worker (from-dims to-dims indices)
- (cond ((null from-dims)
- (apply #'system::set-aref
- (apply #'aref from-array indices)
- to-array indices))
- (t (loop for i below (min (first from-dims)
- (first to-dims))
- do (worker (rest from-dims) (rest to-dims)
- (cons i indices)))))))
- (worker (reverse from-dims) (reverse to-dims) nil))))
-
- (defun weyli::circular-list (&rest arguments)
- #+Genera (apply #'scl:circular-list arguments)
- #-Genera (nconc arguments arguments))
-
- (weyli::defsubst structure-of (x)
- (lisp:type-of x))
-
- ;; The following macros deal with certain functions that should take an
- ;; arbitrary number of arguments.
-
- (defun associate-operation (operation values)
- (labels ((iterate (values result)
- (cond ((null values)
- result)
- (t (iterate (rest values)
- `(,operation ,result ,(first values)))))))
- (iterate (rest values) (first values))))
-
- (defmacro weyli::max (&rest values)
- (cond ((null values)
- (error "Illegal number of arguments to +"))
- ((null (rest values))
- (first values))
- (t (associate-operation 'weyli::max-pair values))))
-
- (defmacro weyli::min (&rest values)
- (cond ((null values)
- (error "Illegal number of arguments to +"))
- ((null (rest values))
- (first values))
- (t (associate-operation 'weyli::min-pair values))))
-
- (defmacro weyli::+ (&rest values)
- (cond ((null values)
- (error "Illegal number of arguments to +"))
- ((null (rest values))
- (first values))
- (t (associate-operation 'weyli::plus values))))
-
- (defmacro weyli::- (&rest values)
- (cond ((null values)
- (error "Illegal number of arguments to +"))
- ((null (rest values))
- `(weyli::minus ,(first values)))
- (t (associate-operation 'weyli::difference values))))
-
- (defmacro weyli::* (&rest values)
- (cond ((null values)
- (error "Illegal number of arguments to +"))
- ((null (rest values))
- (first values))
- (t (associate-operation 'weyli::times values))))
-
- (defmacro weyli::/ (&rest values)
- (cond ((null values)
- (error "Illegal number of arguments to +"))
- ((null (rest values))
- `(weyli::recip ,(first values)))
- (t (associate-operation 'weyli::quotient values))))
-
- #+Genera
- (cp:define-command (com-copy-system-to-unix :command-table "User"
- :provide-output-destination-keyword nil)
- ((sct::*system* 'sct:system)
- &key
- (to-directory '((fs:pathname) :dont-merge-default t)
- :default (sct:system-default-pathname sct::*system*)
- :confirm t
- :prompt "to"
- :documentation "Destination directory ")
- (binary-type 'string :default "SBIN"
- :documentation "Binary extension for Unix")
- (version '(or number (member :latest :newest))
- :default :latest
- :prompt "Version "
- :documentation "Version of system to copy")
- (require-pcl 'boolean
- :default t
- :documentation "True if this system requires that PCL be loaded"))
- (let ((sct::*version* version)
- (sct::*branch* nil)
- (system-plan)
- (system-file))
- (setq system-file
- (send
- (second
- (assoc 'scl:defsystem (get (sct:system-name sct:*system*) :source-file-name)))
- :new-type :lisp))
-
- ;; The idea is reasonable, unfortunately TFTP can't set the creation-date of a file.
- (flet ((update-file (file)
- (let ((to-file (fs:merge-pathnames to-directory file)))
- (unless (eql (getf (rest (second (fs:directory-list file))) :creation-date)
- (getf (rest (second (fs:directory-list to-file))) :creation-date))
- (copy-file file to-file :report-stream *standard-output*)))))
- (update-file system-file)
- (loop for file in (sct:get-all-system-input-files sct:*system* :version version)
- do (update-file file)))
- (setq system-plan (sct:make-plan-for-system :recompile t))
- (with-open-file (stream (fs:merge-pathnames
- (string-downcase
- (format nil "load-~A.lisp"
- (sct:system-name sct:*system*)))
- to-directory)
- :direction :output)
- (princ ";; This file was automatically generated by a program." stream)
- (fresh-line stream)
- (princ ";; Changing it will do no good and the changes will be lost." stream)
- (fresh-line stream)
- (print '(in-package 'user) stream)
- (fresh-line stream)
- (when require-pcl
- (print
- `(unless (find-package 'pcl)
- (load "/usr/fsys/nori/a/pcl/defsys")
- (funcall (intern 'load-pcl 'pcl)))
- stream)
- (fresh-line stream))
- (flet ((compile-file-form (file)
- `(compile-file ,(send (fs:merge-pathnames to-directory file)
- :string-for-host)))
- (load-file-form (file &optional (binary-p t))
- `(load ,(send (fs:merge-pathnames
- (if binary-p
- (send to-directory :new-type binary-type)
- (send to-directory :new-type :lisp))
- file)
- :string-for-host))))
- (print
- `(defun ,(intern (format nil "COMPILE-~A" (sct:system-name sct:*system*))) ()
- ,(load-file-form system-file nil)
- ,@(loop for plan in system-plan
- when (eql (sct:plan-default-input-type plan) :lisp)
- nconc
- (nconc (loop for file in (sct:plan-inputs plan)
- collect (compile-file-form file))
- (loop for file in (sct:plan-inputs plan)
- collect (load-file-form file)))))
- stream)
- (fresh-line stream)
- (print
- `(defun ,(intern (format nil "LOAD-~A" (sct:system-name sct:*system*))) ()
- ,(load-file-form system-file nil)
- ,@(loop for plan in system-plan
- when (eql (sct:plan-default-input-type plan) :lisp)
- nconc
- (loop for file in (sct:plan-inputs plan)
- collect (load-file-form file))))
- stream)))))
-
- #+PCL
- (defvar pcl::*compile-class-hash* (make-hash-table :test #'eq))
-
- #+PCL
- (defun pcl::COMPILE-CLASS-METHODS-1 (classes)
- (clrhash pcl::*compile-class-hash*)
- (dolist (class-spec classes)
- (let ((class (cond ((symbolp class-spec) (pcl::find-class class-spec nil))
- ((pcl::classp class-spec) class-spec))))
- (cond (class
- (dolist (gf (pcl::class-direct-generic-functions class))
- (unless (gethash gf pcl::*compile-class-hash*)
- (setf (gethash gf pcl::*compile-class-hash*) T)
- (pcl::notice-methods-change-1 gf))))
- (t (warn "~A is neither a class nor the name of a class" class-spec))))))
-
- #+PCL
- (defmacro weyli::compile-class-methods (&rest classes)
- `(pcl::compile-class-methods-1 ',classes))
-
- #-PCL
- (defmacro compile-class-methods (&rest classes)
- (declare (ignore classes))
- "Ignored")
-
- #+PCL
- (defun weyli::class-uncompiled-methods (class-spec &optional (function #'print))
- (let ((class (cond ((symbolp class-spec) (pcl::find-class class-spec nil))
- ((pcl::classp class-spec) class-spec))))
- (cond (class
- (dolist (gf (pcl::class-direct-generic-functions class))
- (dolist (method (pcl::generic-function-methods gf))
- (unless (or (compiled-function-p (pcl::method-function method))
- #+Genera
- (typep (pcl::method-function method) 'sys:lexical-closure))
- (funcall function method)))))
- (t (warn "~A is neither a class nor the name of a class" class-spec)))))
-
- #+PCL
- (defun weyli::all-weyl-classes (&optional (function #'print))
- (let (list)
- (labels ((find-sub-classes (class)
- (loop for class in (pcl::class-direct-subclasses class)
- do (unless (member class list)
- (push class list)
- (funcall function class)
- (find-sub-classes class)))))
- (find-sub-classes (pcl::find-class 'weyli::domain))
- (find-sub-classes (pcl::find-class 'weyli::domain-element))
- (find-sub-classes (pcl::find-class 'weyli::morphism)))))
-
- #+PCL
- (defun weyli::all-uncompiled-weyl-methods (&optional (function #'print))
- (let (list generic)
- (weyli::all-weyl-classes
- (lambda (class)
- (weyli::class-uncompiled-methods class
- (lambda (method)
- (setq generic (pcl::method-generic-function method))
- (unless (member generic list)
- (push generic list)
- (funcall function generic))))))))
-